package com.oauth.twitter.server.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Required;

import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

import com.oauth.common.server.beans.OAuthAccessToken;
import com.oauth.common.server.beans.OAuthConfigBean;
import com.oauth.common.server.beans.OAuthRequestToken;
import com.oauth.service.generic.OAuthService;
import com.oauth.service.generic.beans.OAuthServiceBean;
import com.oauth.service.generic.exception.OAuthServiceException;
import com.oauth.twitter.client.beans.Tweet;
import com.oauth.twitter.client.beans.TwitterUser;
import com.oauth.twitter.server.beans.TwitterRequestToken;
import com.oauth.twitter.server.beans.TwitterServiceBean;
import com.oauth.twitter.server.utils.TwitterConversionUtil;

public class TwitterOAuthServiceImpl implements TwitterOAuthService {

	private OAuthService mOAuthService;

	private OAuthConfigBean mOAuthConfigBean;

	private Twitter getTwitter(OAuthAccessToken pAccessToken) {
		return new TwitterFactory().getOAuthAuthorizedInstance(mOAuthConfigBean.getConsumerKey(),
				mOAuthConfigBean.getConsumerSecret(), new AccessToken(pAccessToken.getToken(),
						pAccessToken.getTokenSecret()));
	}

	private Twitter getTwitter() {
		return new TwitterFactory().getOAuthAuthorizedInstance(mOAuthConfigBean.getConsumerKey(),
				mOAuthConfigBean.getConsumerSecret());
	}

	/**
	 * @param pOAuthService
	 *            the oAuthService to set
	 */
	@Required
	public void setOAuthService(OAuthService pOAuthService) {
		mOAuthService = pOAuthService;
	}

	/**
	 * @param pOAuthConfigBean
	 *            the oAuthConfigBean to set
	 */
	@Required
	public void setOAuthConfigBean(OAuthConfigBean pOAuthConfigBean) {
		mOAuthConfigBean = pOAuthConfigBean;
	}

	@Override
	public TwitterRequestToken getRequestToken() throws Exception {
		Twitter twitter = getTwitter();
		RequestToken requestToken = null;
		requestToken = twitter.getOAuthRequestToken(mOAuthConfigBean.getCallBackUrl());
		return new TwitterRequestToken(requestToken.getToken(), requestToken.getTokenSecret(),
				requestToken.getAuthorizationURL());
	}

	@Override
	public OAuthAccessToken getAccessTokenFromDB(Long pMemberId) throws Exception {
		OAuthServiceBean token = null;
		token = mOAuthService.getToken(pMemberId, TwitterServiceBean.class);
		if (token != null) {
			return new OAuthAccessToken(token.getAccessToken(), token.getAccessTokenSecret());
		}
		return null;

	}

	@Override
	public void persistAccessToken(OAuthAccessToken pAccessToken, Long pMemberId)
			throws OAuthServiceException {
		TwitterServiceBean serviceBean = new TwitterServiceBean();
		serviceBean.setAccessToken(pAccessToken.getToken());
		serviceBean.setAccessTokenSecret(pAccessToken.getTokenSecret());
		serviceBean.setMemberId(pMemberId);
		// serviceBean.setTwitterId(twitter.getUserId());
		mOAuthService.persistToken(serviceBean); // persist in db for future
		// use.
	}

	@Override
	public OAuthAccessToken getAccessTokenFromRequestToken(OAuthRequestToken pOAuthTokenBean,
			String pOAuthVerifier) throws Exception {
		AccessToken accessToken = getTwitter().getOAuthAccessToken(pOAuthTokenBean.getToken(),
				pOAuthTokenBean.getTokenSecret(), pOAuthVerifier);
		return new OAuthAccessToken(accessToken.getToken(), accessToken.getTokenSecret());

	}

	@Override
	public Tweet updateTweet(String pTweetText, Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		Twitter twitter = getTwitter(accessToken);
		Status updateTweet = twitter.updateStatus(pTweetText);
		return TwitterConversionUtil.convertToTweet(updateTweet);
	}

	@Override
	public List<Tweet> getTweets(Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		Twitter twitter = getTwitter(accessToken);
		ResponseList<Status> userTimeline = twitter.getHomeTimeline();
		return TwitterConversionUtil.convertToTweets(userTimeline);
	}

	@Override
	public TwitterUser getUserInfo(Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		Twitter twitter = getTwitter(accessToken);
		User user = twitter.showUser(twitter.getId());
		return TwitterConversionUtil.convertToUser(user);

	}
}
